rate-limiter-flexible 是 Node.js 常用限流库,支持内存、Redis 等存储。
1. 基础限流
npm install rate-limiter-flexible
const { RateLimiterMemory } = require('rate-limiter-flexible');
const limiter = new RateLimiterMemory({
points: 5, // 允许 5 次
duration: 60, // 60 秒内
});
async function request(ip) {
try {
await limiter.consume(ip);
console.log('请求通过');
} catch (rejRes) {
console.log(`请求过于频繁,请 ${Math.ceil(rejRes.msBeforeNext / 1000)} 秒后重试`);
}
}
request('127.0.0.1');
2. Express 中使用
const express = require('express');
const { RateLimiterMemory } = require('rate-limiter-flexible');
const app = express();
const limiter = new RateLimiterMemory({
points: 100,
duration: 60,
});
app.use(async (req, res, next) => {
try {
await limiter.consume(req.ip);
next();
} catch (rejRes) {
res.status(429).json({
message: '请求过于频繁',
retryAfter: Math.ceil(rejRes.msBeforeNext / 1000),
});
}
});
app.get('/', (req, res) => res.send('OK'));
app.listen(3000);
3. Redis 存储
npm install rate-limiter-flexible ioredis
const Redis = require('ioredis');
const {
RateLimiterRedis,
} = require('rate-limiter-flexible');
const redisClient = new Redis();
const limiter = new RateLimiterRedis({
storeClient: redisClient,
keyPrefix: 'rate-limit',
points: 10,
duration: 60,
});
await limiter.consume('user:1001');
4. 登录失败限制
const limiter = new RateLimiterMemory({
points: 5,
duration: 900, // 15 分钟
});
async function login(username, ip) {
const key = `${username}_${ip}`;
try {
await limiter.consume(key);
// 执行登录逻辑
} catch {
throw new Error('登录失败次数过多,请稍后再试');
}
}